export default class HttpBean {
    param: paramType = {} as any

    constructor(param: paramType) {
        this.param = param
    }

    post<T = any>(optoins: any, data: any = {}): Promise<Res<T>> {
        return this.request(optoins, data, 'POST')
    }

    get<T = any>(optoins: any, data: any = {}): Promise<Res<T>> {
        return this.request(optoins, data, 'GET')
    }

    private request<T = any>(optoins: any, data: any = {}, method: 'POST' | 'GET'): Promise<Res<T>> {
        const param = this.param
        return new Promise<Res<T>>((resolve) => {
            let url = optoins
            let headerOptions = {} as any
            if (typeof optoins !== 'string') {
                url = optoins.url
                if (optoins.method) method = optoins.method
                if (optoins.header) headerOptions = optoins.header
            }
            let headerObj = {
                'content-type': 'application/json;charset=UTF-8'
            }
            if (param.req) param.req(headerObj, optoins)
            headerObj = Object.assign(headerObj, headerOptions)
            const rObj: UniNamespace.RequestOptions = {
                url: param.baseUrl + url,
                method: method,
                data: data,
                header: headerObj,
                timeout: param.outtime ?? 30000,
                success: (response: any) => {
                    if (response.statusCode !== 200) {
                        param.error ? param.error(response) : 0
                        resolve(<Res<T>>{ status: false })
                        return
                    }
                    let res: Res = response.data
                    if (optoins.resource) {
                        resolve(<Res<T>>res)
                        return
                    }
                    if (res.code) {
                        res.code += ''
                        if (res.status === undefined) res.status = res.code === '200'
                    }
                    if (param.res) param.res(res, optoins)
                    resolve(<Res<T>>res)
                },
                fail: (error: any) => {
                    param.error ? param.error(error) : 0
                    resolve(<Res<T>>{ status: false })
                },
                complete: () => {}
            }

            if (optoins.responseType) rObj.responseType = optoins.responseType

            uni.request(rObj)
        })
    }
}

export interface Res<T = any> {
    /**
     * 消息代码
     */
    code: string
    /**
     * 消息状态，code是200时为true，其他为false，如果返回了该字段则不进行处理
     */
    status: boolean
    /**
     * 使用消息字段1
     */
    message: string
    /**
     * 请求返回数据
     */
    data: T
    /**
     * 数组长度
     */
    total: number
}

type paramType = {
    baseUrl: string
    /**
     * 请求前处理
     * @param config
     * @returns
     */
    req?: (config: any, options: any) => void
    /**
     * 请求后处理
     * @param config
     * @returns
     */
    res?: (res: any, options: any) => any
    /**
     * 错误处理
     * @param res
     * @returns
     */
    error?: (res: any) => any

    /**
     * 超时时间
     */
    outtime?: number
}
